package solutions.ferpa.ztest.ent;

import java.sql.*;
import java.util.ArrayList;
import br.com.telescope.adsrt.dom.*;
import br.com.telescope.adsrt.lib.*;
import br.com.telescope.t2.exception.Severity;
import java.sql.*;
import java.util.UUID;

/**
 * API de persistência de dados da entidade BILHETES_ENTRADA
 * @author Gerado pelo Telescope
 */
public class EntBilhetesEntrada extends Entity {
    
    public final static String ENTITY_NAME = "RTAUTH.BILHETES_ENTRADA";
    public final static String TABLE_NAME = "BILHETES_ENTRADA";
    
    // <editor-fold defaultstate="collapsed" desc="Contrutores e inicializacao">
    /**
     * Construtores
     */
    public EntBilhetesEntrada() {
        super();
        initialize();
    }
    
    public EntBilhetesEntrada(BaseRuntime ctx) {
        super();
        initialize(ctx);
    }
    
    @Override
    public String getPrimaryKeyColumn() {
        return "ID";
    }
    
    @Override
    public void initialize(BaseRuntime ctx) {
        super.initialize(ctx);
        initialize();
    }
    
    public void initialize() {
        aCodigo = new DomText(this,"CODIGO", "Código"); 
        aCodigo.setSize(80);
        oCodigo = new DomText();
        aId = new DomId(this,"ID", "Id"); 
        aId.setRequired(true);
        oId = new DomId();
        aUltimaEntrada = new DomDateTime(this,"ULTIMA_ENTRADA", "Última entrada"); 
        aUltimaEntrada.setRequired(true);
        oUltimaEntrada = new DomDateTime();
        aUsuarioId = new DomId(this,"USUARIO_ID", "Usuário"); 
        aUsuarioId.setRequired(true);
        oUsuarioId = new DomId();
        ressetModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributos da entidade">
    
    // Código
    private DomText aCodigo;
    private DomText oCodigo;
    
    // Id
    private DomId aId;
    private DomId oId;
    
    // Última entrada
    private DomDateTime aUltimaEntrada;
    private DomDateTime oUltimaEntrada;
    
    // Usuário
    private DomId aUsuarioId;
    private DomId oUsuarioId;
    
    // <editor-fold defaultstate="collapsed" desc="Atributo CODIGO">
    
    public EntBilhetesEntrada codigo(String value) {
        setCodigo(value);
        return this;
    }
    
    public void setCodigo(DomText value) {
        if (value == null || value.isNull()) {
            nullifyCodigo();
        } else {
            aCodigo.setValue(value.getValue());
            if (aCodigo.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setCodigo(String value) {
        if (value == null) {
            nullifyCodigo();
        } else {
            aCodigo.setValue(value);
            if (aCodigo.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setCodigo(Object value) {
        aCodigo.setValue(value);
        if (aCodigo.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifyCodigo() {
        if (!aCodigo.isNull()) {
            aCodigo.setNull(true);
            setModified(true);
        }
    }
    
    public DomText getCodigo() {
        return aCodigo;
    }
    
    public DomText oldCodigo() {
        return oCodigo;
    }
    
    public String valueOfCodigo() {
        return aCodigo.getValue();
    }
    
    public boolean isCodigoModified() {
        return aCodigo.isModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributo ID">
    
    public EntBilhetesEntrada id(Long value) {
        setId(value);
        return this;
    }
    
    public void setId(DomId value) {
        if (value == null || value.isNull()) {
            nullifyId();
        } else {
            aId.setValue(value.getValue());
            if (aId.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setId(String value) {
        if (value == null) {
            nullifyId();
        } else {
            aId.setValue(value);
            if (aId.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setId(Long value) {
        aId.setValue(value);
        if (aId.isModified()) {
            setModified(true);
        }
    }
    
    public void setId(Object value) {
        aId.setValue(value);
        if (aId.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifyId() {
        if (!aId.isNull()) {
            aId.setNull(true);
            setModified(true);
        }
    }
    
    public DomId getId() {
        return aId;
    }
    
    public DomId oldId() {
        return oId;
    }
    
    public Long valueOfId() {
        return aId.getValue();
    }
    
    public boolean isIdModified() {
        return aId.isModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributo ULTIMA_ENTRADA">
    
    public EntBilhetesEntrada ultimaEntrada(java.sql.Timestamp value) {
        setUltimaEntrada(value);
        return this;
    }
    
    public void setUltimaEntrada(DomDateTime value) {
        if (value == null || value.isNull()) {
            nullifyUltimaEntrada();
        } else {
            aUltimaEntrada.setValue(value.getValue());
            if (aUltimaEntrada.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setUltimaEntrada(String value) {
        if (value == null) {
            nullifyUltimaEntrada();
        } else {
            aUltimaEntrada.setValue(value);
            if (aUltimaEntrada.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setUltimaEntrada(java.sql.Timestamp value) {
        aUltimaEntrada.setValue(value);
        if (aUltimaEntrada.isModified()) {
            setModified(true);
        }
    }
    
    public void setUltimaEntrada(Object value) {
        aUltimaEntrada.setValue(value);
        if (aUltimaEntrada.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifyUltimaEntrada() {
        if (!aUltimaEntrada.isNull()) {
            aUltimaEntrada.setNull(true);
            setModified(true);
        }
    }
    
    public DomDateTime getUltimaEntrada() {
        return aUltimaEntrada;
    }
    
    public DomDateTime oldUltimaEntrada() {
        return oUltimaEntrada;
    }
    
    public java.sql.Timestamp valueOfUltimaEntrada() {
        return aUltimaEntrada.getValue();
    }
    
    public boolean isUltimaEntradaModified() {
        return aUltimaEntrada.isModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributo USUARIO_ID">
    
    public EntBilhetesEntrada usuarioId(Long value) {
        setUsuarioId(value);
        return this;
    }
    
    public void setUsuarioId(DomId value) {
        if (value == null || value.isNull()) {
            nullifyUsuarioId();
        } else {
            aUsuarioId.setValue(value.getValue());
            if (aUsuarioId.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setUsuarioId(String value) {
        if (value == null) {
            nullifyUsuarioId();
        } else {
            aUsuarioId.setValue(value);
            if (aUsuarioId.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setUsuarioId(Long value) {
        aUsuarioId.setValue(value);
        if (aUsuarioId.isModified()) {
            setModified(true);
        }
    }
    
    public void setUsuarioId(Object value) {
        aUsuarioId.setValue(value);
        if (aUsuarioId.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifyUsuarioId() {
        if (!aUsuarioId.isNull()) {
            aUsuarioId.setNull(true);
            setModified(true);
        }
    }
    
    public DomId getUsuarioId() {
        return aUsuarioId;
    }
    
    public DomId oldUsuarioId() {
        return oUsuarioId;
    }
    
    public Long valueOfUsuarioId() {
        return aUsuarioId.getValue();
    }
    
    public boolean isUsuarioIdModified() {
        return aUsuarioId.isModified();
    }
    // </editor-fold>
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="getErrors">
    /**
     * Traduz um erro recebido do banco de dados para um AdsException
     */
    @Override
    public AdsException getErrors(String errorMsg, int transaction) {
        AdsException e;
        String msg = errorMsg.toUpperCase();
        
        if (transaction == DELETE_TRANSACTION) {
            e = new AdsException("RTAUTH.BILHETES_ENTRADA.GET_ERRORS_UNKNOWN",
                    AdsException.UNKNOWN,
                    "Erro não esperado: " + errorMsg);
        } else {
            if (msg.indexOf("PK_BIEN") >= 0) {
                e = new AdsException("RTAUTH.BILHETES_ENTRADA.PK_BIEN", 
                        Severity.ERROR,
                        "ID duplicado! (PK_BIEN)");
                return e;
            } else if (msg.indexOf("UK_BIEN_CODIGO") >= 0) {
                e = new AdsException("RTAUTH.BILHETES_ENTRADA.UK_BIEN_CODIGO", 
                        Severity.ERROR,
                        "Registro duplicado! Código ${CODIGO} (UK_BIEN_CODIGO)");
                return e;
            } else if (msg.indexOf("FK_BIEN_USUA_USUARIO") >= 0) {
                e = new AdsException("RTAUTH.BILHETES_ENTRADA.FK_BIEN_USUA_USUARIO", 
                        Severity.ERROR,
                        "Registro não cadastrado para USUARIO! (FK_BIEN_USUA_USUARIO)");
                return e;
            } else {
                e = new AdsException("RTAUTH.BILHETES_ENTRADA.GET_ERRORS_UNKNOWN",
                        AdsException.UNKNOWN,
                        "Erro não esperado: " + errorMsg);
            }
        }
        return e;
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Entity Information">
    
    public String getEntityName() {
        return ENTITY_NAME;
    }
    
    public String getTableName() {
        return TABLE_NAME;
    }
    
    public String idSequenceName() {
        return "PK_SEQUENCE";
    }
    
    private ArrayList<Field> allAttributes;
    public ArrayList<Field> getAllAttributes() {
        if (allAttributes == null) {
            allAttributes = new ArrayList<Field>();
            allAttributes.add(aCodigo);
            allAttributes.add(aId);
            allAttributes.add(aUltimaEntrada);
            allAttributes.add(aUsuarioId);
        }
        return allAttributes;
    }
    
    /**
     * Retorna o valor da primeira UK da entidade
     * Se ela for composta, retorna a concatenação de toda a combinação
     * de atributos separados por um espaço.
     */
    public String valueOfUk() {
        return getCodigo().toString();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Relationships">
    
    
    public void findByCodigo(String codigo) throws AdsException {
        findBy(new String[] {"CODIGO"},
                new Object[] {codigo});
    }
    
    private EntUsuarios eUsuario;
    
    public EntUsuarios findUsuario() throws AdsException {
        if (getUsuarioId().isNull()) {
            return null;
        }
        if (eUsuario == null || !valueOfUsuarioId().equals(eUsuario.valueOfId())) {
            eUsuario = new EntUsuarios(ctx);
            eUsuario.find(valueOfUsuarioId());
        }
        return eUsuario;
    }
    
    /**
     * Ativa o join desta entidade com USUARIOS
     * através do atributo USUARIO_ID
     */
    public EntUsuarios joinUsuario() {
        return joinUsuario(null);
    }
    public EntUsuarios joinUsuario(String alias) {
        EntUsuarios entity = new EntUsuarios(ctx);
        if (alias != null) {
            entity.setAlias(alias);
        }
        Join newJoin = new Join(getUsuarioId(), entity);
        entity.setJoinedBy(newJoin);
        this.join(newJoin);
        return entity;
    }
    
    public void findByUsuario(long id, String sqlAppend) throws AdsException {
        find("select ID from BILHETES_ENTRADA where USUARIO_ID = ? " + sqlAppend);
        sqlSetLong(1,id);
    }
    
    public void findByUsuario(long id) throws AdsException {
        findByUsuario(id,"");
    }
    
    public void findByUsuario(Entity entidade) throws AdsException {
        findByUsuario(entidade.valueOfId(),"");
    }
    
    public void findByUsuario(Entity entidade, String sqlAppend) throws AdsException {
        findByUsuario(entidade.valueOfId(),sqlAppend);
    }
    
    /**
     * Limpa os objetos normalizados da entidade
     */
    public void clearRelatedObjects() {
        eUsuario = null;
    }
    
    /**
     * Método que copia os valores dos atributos
     * para os valores respectivos old 
     */
    public void saveOldAtributes() {
        oId.setValue(aId);
        oUsuarioId.setValue(aUsuarioId);
        oUltimaEntrada.setValue(aUltimaEntrada);
        oCodigo.setValue(aCodigo);
    }
    
    /**
     * Método que retorna as regras da entidade
     * @return ArrayList com as regras ou null caso não existir nenhuma regra
     */
    public ArrayList getAllRules() {
        ArrayList<EntityRule> out = new ArrayList<EntityRule>();
        {
            UniqueKeyRule rule = new UniqueKeyRule();
            rule.setEntity(EntBilhetesEntrada.class);
            rule.setName("UK_BIEN_CODIGO");
            rule.addAttribute(new DomText("CODIGO",""));
            out.add(rule);
        }
        {
            ForeignKeyRule rule = new ForeignKeyRule();
            rule.setEntity(EntBilhetesEntrada.class);
            rule.setAssociatedEntity(EntUsuarios.class);
            rule.setName("FK_BIEN_USUA_USUARIO");
            rule.addAttribute(new DomId("USUARIO_ID",""));
            out.add(rule);
        }
        {
            PrimaryKeyRule rule = new PrimaryKeyRule();
            rule.setEntity(EntBilhetesEntrada.class);
            rule.setName("PK_BIEN");
            rule.setPkAttribute(new DomId("ID",""));
            out.add(rule);
        }
        return out;
    }
    // </editor-fold>
    
    @Override
    protected void preInsert() throws AdsException {
        // Calcular o código do bilhete de entrada
        {
            ctx.logStart("ENT-EVE", "RTAUTH.BILHETES_ENTRADA", "Calcular o código do bilhete de entrada");
            calcularCodigo();
            ctx.logFinish();
        }
        // Atualizar a ultima entrada
        {
            ctx.logStart("ENT-EVE", "RTAUTH.BILHETES_ENTRADA", "Atualizar a ultima entrada");
            atualizarUltimaEntrada();
            ctx.logFinish();
        }
    }
    
    @Override
    protected void preUpdate() throws AdsException {
        // Atualizar a ultima entrada
        {
            ctx.logStart("ENT-EVE", "RTAUTH.BILHETES_ENTRADA", "Atualizar a ultima entrada");
            atualizarUltimaEntrada();
            ctx.logFinish();
        }
    }
    
    @Override
    public void fillDefaultValues() throws AdsException {
        if (aId.isNull()) {
            aId.setValue("" + ctx.getNextVal("pk_sequence"));
        }
    }
    
    // <editor-fold defaultstate="collapsed" desc="Métodos customizados">
    
    /**
     * Atualizar a ultima entrada.
     * <p>
     * Sempre que inserir ou atualizar o registro, a ultima entrada é 
     * atualizada para a data e hora do sistema.
     */
    private void atualizarUltimaEntrada() throws AdsException {
        // <user-code id="36368" parentId="36366" hashcode="-608c2ed0" length="83">
        // import java.sql.*;
        setUltimaEntrada(new Timestamp(System.currentTimeMillis()));
        // </user-code>
    }
    
    /**
     * Calcular o código do bilhete de entrada.
     * <p>
     * Calcula e preenche o código do bilhete de entrada com uma sequencia 
     * aleatória.
     */
    private void calcularCodigo() throws AdsException {
        // <user-code id="36338" parentId="36326" hashcode="aa11c84" length="247">
        // import java.util.UUID;
        
        try {
            setCodigo(UUID.randomUUID().toString());
        } catch (Throwable e) {
            // Ambientes sem java 1.5 irão utilizar a sequence
            setCodigo(ads.getNextVal("pk_sequence") + "" + System.currentTimeMillis());
        }
        
        // </user-code>
    }
    
    /**
     * Excluir bilhetes de entrada expirados.
     * <p>
     * Este procedimento exclui todos os bilhetes de entrada que tem estão 
     * expirados.
     * <P>
     * Um bilhete de entrada é considerado usado se seu último uso excede ao 
     * tempo parametrizado na propriedade 
     * ADSRT.BILHETES_ENTRADA.TEMPO_RETENCAO (valor registrado em horas)
     * <P>
     * <p>
     * <P>
     * Este procedimento é chamado por eventos externos.
     * <P>
     */
    public void excluirExpirados() throws AdsException {
        // <user-code id="36348" parentId="36343" hashcode="-366ac36e" length="217">
        // Pesquisa e exclui todos cuja ultima entrada é inferior a menor válida
        find("select id from bilhetes_entrada where ultima_entrada < ?");
        sqlSetTimestamp(1,menorDataValida());
        while (next()) { del(); }
        close();
        
        // </user-code>
    }
    
    /**
     * Retorna se o bilhete ainda á válido!.
     * <p>
     * Verifica se o bilhete é válido, ou seja, tem um usuário válido e ainda 
     * não expirou.
     */
    public boolean isValid() throws AdsException {
        // <user-code id="36361" parentId="36353" hashcode="4efaac9d" length="90">
        return ( getUsuarioId().isNotNull() && valueOfUltimaEntrada().after(menorDataValida()));
        
        // </user-code>
    }
    
    /**
     * Retorna a menor data válida para bilhetes de dentrada.
     * <p>
     * Retorna a menor data válida para bilhetes de dentrada.
     */
    private java.sql.Timestamp menorDataValida() throws AdsException {
        // <user-code id="36357" parentId="36355" hashcode="-3f804989" length="174">
        return new Timestamp(
                System.currentTimeMillis() - 
                3600000 *
                Long.parseLong(ctx.getPreference("ADSRT.BILHETES_ENTRADA.TEMPO_RETENCAO","168")) );
        
        // </user-code>
    }
}
